package org.example.rowing.controller.raceProcessController;

import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.util.StringConverter;
import lombok.extern.slf4j.Slf4j;
import org.example.rowing.controller.LaneExportController;
import org.example.rowing.controller.util.NavigationUtil;
import org.example.rowing.domain.RoundScore;
import org.example.rowing.domain.Team;
import org.example.rowing.service.*;
import org.example.rowing.vo.RaceVO;
import org.example.rowing.vo.RegistrationVO;
import org.example.rowing.vo.RoundScoreVO;
import org.example.rowing.vo.TeamVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Controller
@Slf4j
public class CKRaceProcessController {


    @FXML
    public Button randomButton;
    @FXML
    public Button nextRoundButton;
    @FXML
    public Button exportLaneButton;
    @FXML
    public TableColumn<RoundScoreVO, String> laneColumn;
    @FXML
    public TableColumn<RoundScoreVO, String> registrationIdColumn;
    @FXML
    public TableColumn<RoundScoreVO, String> teamNameColumn;
    @FXML
    public TableColumn<RoundScoreVO, Double> timeColumn;
    @FXML
    public TableView<RoundScoreVO> resultsTable;
    @FXML
    public Label currentRoundLabel;
    @FXML
    private TextField minutesInput;
    @FXML
    private TextField secondsInput;
    @FXML
    private TextField hundredthsInput;
    @FXML
    private ComboBox<RoundScoreVO> laneComboBox;
    private ObservableList<RoundScoreVO> resultsList;

    private Long raceId;
    private RaceVO raceVO;
    private boolean lotteryDone;

    @Autowired
    private CKDrawLotteryService drawLotteryService;
    @Autowired
    private RaceInfoService raceInfoService;
    @Autowired
    private RaceProcessCommonService raceProcessCommonService;
    @Autowired
    private Map<String, RaceProcessStrategy> raceProcessStrategies; // 根据Bean名称注入

    // 定义比赛阶段顺序
    private static final List<String> ROUND_ORDER = Arrays.asList(
            "预赛",
            "半决赛",
            "决赛",
            "比赛结果"
    );

    @FXML
    public void initialize(RaceVO raceVO) {
        // 设置时间列的格式化显示
        timeColumn.setCellFactory(column -> new TableCell<RoundScoreVO, Double>() {
            @Override
            protected void updateItem(Double time, boolean empty) {
                super.updateItem(time, empty);

                if (empty || time == null) {
                    setText(null);
                } else {
                    // 格式化为 x1:x2.x3 格式
                    int minutes = (int) (time / 60);
                    int seconds = (int) (time % 60);
                    int hundredths = (int) ((time * 100) % 100);
                    setText(String.format("%d:%02d.%02d", minutes, seconds, hundredths));
                }
            }
        });

        // 设置表格列
        laneColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getLane()));
        registrationIdColumn.setCellValueFactory(cellData -> new SimpleStringProperty(String.valueOf(cellData.getValue().getRegistrationVO().getRegistrationId())));
        teamNameColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getRegistrationVO().getTeam().getName()));
        timeColumn.setCellValueFactory(cellData -> new ReadOnlyObjectWrapper<>(cellData.getValue().getScore()));

        this.raceId = raceVO.getId();
        this.raceVO = raceVO;
        this.lotteryDone = false;
        List<RegistrationVO> teams = raceProcessCommonService.getRegistrationVOS(raceVO);
        int teamCount = teams.size();
        log.info("raceId---------------------------: {}", raceId);

        Map<RegistrationVO, String> lotteryResult = drawLotteryService.getLotteryResult(raceId, teamCount);
        if (lotteryResult != null && !lotteryResult.isEmpty()) {
            lotteryDone = true;
        }

        // 初始化赛事列表（默认展示一些数据）
        RoundScoreVO condition = new RoundScoreVO();
        condition.setRaceId(raceId);
        condition.setRound("预赛");
        List<RoundScoreVO> roundScoreVOS = raceInfoService.showRoundScoreByCondition(condition);
        resultsList = FXCollections.observableArrayList(roundScoreVOS);
        resultsTable.setItems(resultsList);

        // 初始化下拉框
        updateLaneComboBox();

        // 监听表格数据变化，自动更新下拉框
        resultsList.addListener((ListChangeListener<RoundScoreVO>) c -> {
            updateLaneComboBox();
        });
    }

    // 根据队伍数量选择策略
    private RaceProcessStrategy getRaceProcessStrategy(int teamCount) {
        if (teamCount >= 3 && teamCount <= 9) {
            return raceProcessStrategies.get("CKProcessThreeToNineBoatsService");
        } else if (teamCount >= 10 && teamCount <= 18) {
            return raceProcessStrategies.get("CKProcessTenToEighteenBoatsService");
        } else if (teamCount >= 19 && teamCount <= 27) {
            return raceProcessStrategies.get("CKProcessNineteenToTwentySevenBoatsService");
        } else if (teamCount >= 28 && teamCount <= 36) {
            return raceProcessStrategies.get("CKProcessTwentyEightToThirtySixBoatsService");
        } else if (teamCount >= 37 && teamCount <= 45) {
            return raceProcessStrategies.get("CKProcessThirtySevenToFortyFiveBoatsService");
        } else if (teamCount >= 46 && teamCount <= 54) {
            return raceProcessStrategies.get("CKProcessFortySixToFiftyFourBoatsService");
        } else if (teamCount >= 55 && teamCount <= 63) {
            return raceProcessStrategies.get("CKProcessFiftyFiveToSixtyThreeBoatsService");
        } else if (teamCount >= 64 && teamCount <= 72) {
            return raceProcessStrategies.get("CKProcessSixtyFourToSeventyTwoBoatsService");
        } else {
            return null;
        }
    }

    public void handleGenerateNextRound(ActionEvent event) {
        List<RegistrationVO> teams = raceProcessCommonService.getRegistrationVOS(raceVO);
        int teamCount = teams.size();
        List<RoundScoreVO> curRounds = new ArrayList<>(resultsTable.getItems());
        boolean isDataValid = !curRounds.isEmpty() && curRounds.stream().allMatch(vo -> vo.getScore() != null);
        String currentRound = currentRoundLabel.getText();

        if (!isDataValid) {
            showErrorDialog("当前比赛未结束，无法晋级下一轮。请输入当前比赛的所有成绩！");
            return;
        }

        RaceProcessStrategy strategy = getRaceProcessStrategy(teamCount);

        switch (currentRound) {
            case "预赛":
                strategy.getAdvancingToHalfFinals(curRounds, raceId);
                strategy.getAdvancingToFinals(curRounds, raceId);
                updateRoundDisplay("半决赛");
                break;
            case "半决赛":
                strategy.getHalfFinalsToFinals(curRounds, raceId);
                updateRoundDisplay("决赛");
                break;
            case "决赛":
                List<RoundScoreVO> rank = strategy.getRank(curRounds, raceVO);
                log.info("排名：{}", rank);
                updateRoundDisplay("比赛结果");
                break;
            default:
                showErrorDialog("未知比赛阶段！");
        }

        log.info("晋级信息已更新");
    }

    public void handleTimeCommitClick(ActionEvent event) {
        if (!lotteryDone) {
            showErrorDialog("请先进行抽签！");
            return;
        }
        RoundScoreVO selectedVO = laneComboBox.getSelectionModel().getSelectedItem();
        // 获取三个时间字段的值
        String minutesText = minutesInput.getText();
        String secondsText = secondsInput.getText();
        String hundredthsText = hundredthsInput.getText();

        // 校验输入
        if (selectedVO == null) {
            showErrorDialog("请选择赛道号！");
            return;
        }
        if (minutesText == null || secondsText == null || hundredthsText == null ||
                minutesText.isEmpty() || secondsText.isEmpty() || hundredthsText.isEmpty()) {
            showErrorDialog("请完整输入比赛用时！");
            return;
        }

        try {
            int minutes = Integer.parseInt(minutesText);
            int seconds = Integer.parseInt(secondsText);
            int hundredths = Integer.parseInt(hundredthsText);

            // 验证时间范围
            if (minutes < 0 || seconds < 0 || seconds > 59 || hundredths < 0 || hundredths > 99) {
                showErrorDialog("时间输入无效！分钟≥0，秒(0-59)，百分秒(0-99)");
                return;
            }

            // 计算总秒数
            double totalSeconds = minutes * 60.0 + seconds + hundredths / 100.0;

            // 直接更新选中项的成绩
            selectedVO.setScore(totalSeconds);

            // 保存到数据库
            RoundScore roundScore = new RoundScore(
                    selectedVO.getRaceId(),
                    selectedVO.getRound(),
                    null,
                    selectedVO.getLane(),
                    selectedVO.getScore(),
                    selectedVO.getRegistrationVO().getRegistrationId(),
                    selectedVO.getStatus()
            );
            raceInfoService.saveRoundScore(roundScore);

            // 清空输入
            minutesInput.clear();
            secondsInput.clear();
            hundredthsInput.clear();
            laneComboBox.getSelectionModel().clearSelection();

            // 刷新表格（直接操作数据源，无需重新加载）
            resultsTable.refresh();
        } catch (NumberFormatException e) {
            showErrorDialog("时间必须为整数！");
        }
    }

    public void handlePrevRoundClick(ActionEvent event) {
        // 获取当前阶段索引
        int currentIndex = ROUND_ORDER.indexOf(currentRoundLabel.getText());

        // 如果当前是第一个阶段，无法回退
        if (currentIndex <= 0) {
            showErrorDialog("已经是第一个阶段！");
            return;
        }

        // 更新到上一阶段
        String prevRound = ROUND_ORDER.get(currentIndex - 1);
        updateRoundDisplay(prevRound);
    }

    public void handleNextRoundClick(ActionEvent event) {
        // 获取当前阶段索引
        int currentIndex = ROUND_ORDER.indexOf(currentRoundLabel.getText());

        // 如果当前是最后一个阶段，无法前进
        if (currentIndex >= ROUND_ORDER.size() - 1) {
            showErrorDialog("已经是最后一个阶段！");
            return;
        }

        // 更新到下一阶段
        String nextRound = ROUND_ORDER.get(currentIndex + 1);
        updateRoundDisplay(nextRound);
    }

    // 更新阶段显示和表格数据
    private void updateRoundDisplay(String round) {
        // 1. 更新阶段标签
        currentRoundLabel.setText(round);

        // 2. 加载对应阶段的数据
        RoundScoreVO condition = new RoundScoreVO();
        condition.setRaceId(raceId);
        condition.setRound(round);

        List<RoundScoreVO> roundData = raceInfoService.showRoundScoreByCondition(condition);

        // 3. 刷新表格
        resultsList.setAll(roundData);
        resultsTable.refresh();
    }

    private void updateInitRoundDisplay(String round) {
        this.lotteryDone = true;
        updateRoundDisplay(round);
    }

    private void updateLaneComboBox() {
        if (currentRoundLabel.getText().equals("比赛结果")) {
            laneComboBox.setItems(null);
        } else {
            // 直接绑定表格数据（假设 resultsList 是 ObservableList<RoundScoreVO>）
            laneComboBox.setItems(resultsList);
        }

        // 自定义下拉框显示内容（仅显示 lane）
        laneComboBox.setCellFactory(param -> new ListCell<RoundScoreVO>() {
            @Override
            protected void updateItem(RoundScoreVO vo, boolean empty) {
                super.updateItem(vo, empty);
                setText(empty || vo == null ? "" : vo.getLane());
            }
        });

        // 自定义选中项显示内容（避免选中时显示对象地址）
        laneComboBox.setConverter(new StringConverter<RoundScoreVO>() {
            @Override
            public String toString(RoundScoreVO vo) {
                return vo == null ? "" : vo.getLane();
            }

            @Override
            public RoundScoreVO fromString(String lane) {
                // 若需支持手动输入，需实现反向解析（此处通常不需要）
                return null;
            }
        });
    }

    public void handleRandomClick(ActionEvent event) {
        log.info("进入抽签: {}", event.getSource());
        NavigationUtil.showPopup(
                "/fxml/canoeAndKayakViews/raceProcessView/CKRandomView.fxml",
                "查看抽签",
                randomButton.getScene().getWindow(),
                controller -> {
                    if (controller instanceof CKDrawLotteryController drawLotteryController) {
                        drawLotteryController.setConfirmCallback(this::updateInitRoundDisplay);
                        drawLotteryController.initialize(raceId);
                    }
                }
        );
    }

    private void showErrorDialog(String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle("输入错误");
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }

    @FXML
    public void handleExportLaneEvent(ActionEvent event) {
        // 打开添加赛事界面的逻辑
        log.info("开始选择导出项目");
        NavigationUtil.showPopup(
                NavigationUtil.viewMap.get(exportLaneButton.getId()),
                "选择导出确认单的队伍",
                exportLaneButton.getScene().getWindow(),
                controller -> {
                    if (controller instanceof LaneExportController) {
                        ((LaneExportController) controller).initialize(raceId);
                    }
                }
        );
    }
}
